#include "TcpServer.hpp"
#include <memory>

using namespace tcpserver;

static  void usage(std::string proc)
{
    std::cerr<<"Usage:\n\t "<<proc<<"   port"<<"\n\n";
}

bool cal(const Request &req, Response &resp)
{
    resp._exitcode=OK;
    resp._result=OK;
    std::map<char,std::function<int(int, int)>> opFunMap =
        {
            {'+', [](int x, int y){ return x + y; }},
            {'-', [](int x, int y){ return x - y; }},
            {'*', [](int x, int y){ return x * y; }},
            {'/', [&](int x, int y)
            {if(y==0) {resp._exitcode=DIV_ZERO; return y;} return x / y; }},
            {'%', [&](int x, int y)
            { if(y==0) {resp._exitcode=MOD_ZERO; return y;} return x % y; }}
        };
 
    if(opFunMap.find(req._op)!=opFunMap.end())
    {
        resp._result=opFunMap[req._op](req._x,req._y);
    }
    else
    {
        resp._exitcode=OP_ERROR;
    }

    return true;
}


void calculate(Connection *conn)
{
    std::string onePackage;
    while(ParseOnePackage(conn->_inbuffer,&onePackage))
    {
        std::string reqStr;
        if(!deLength(onePackage,&reqStr))
            return;
        std::cout<<"去掉报文的正文: \n "<<reqStr<<std::endl;

        Request req;
        if(!req.deserialize(reqStr))
            return;

        Response resp;
        cal(req,resp);

        std::string respStr;
        resp.serialize(&respStr);
        // 5. 然后我们在发送响应
        // 5.1 构建成为一个完整的报文
        conn->_outbuffer+=enLength(respStr);
        // send(sock,send_string.c_str(),send_string.size(),0);

        //发送数据
        std::cout<<"-----------rsepStr:\n "<<respStr<<std::endl;
        if(conn->_sender)conn->_sender(conn);
        
        //如果没有发完数据，需要对对应的sock开启对写事件的关心，如果发完了，要关闭对写事件的关心
        // if(!conn->_outbuffer.empty()) conn->_tsp->EnableReadWrite(conn,true ,true);
        // else conn->_tsp->EnableReadWrite(conn,true ,false);
    }
}

int main(int argc,char* argv[])
{
    if(argc!=2)
    {
        usage(argv[0]);
        exit(-1);
    }
    uint16_t port=atoi(argv[1]);
    std::unique_ptr<TcpServer> tsvr(new TcpServer(calculate,port));
    tsvr->initserver();
    tsvr->Dispath();
    return 0;
}